package mammuthus.web.action

import org.springframework.web.bind.annotation.{RequestMethod, RequestMapping}
import javax.servlet.http.HttpServletRequest
import java.util
import mammuthus.web.bean.{ SlaveBean}
import mammuthus.web.util.Constants
import scala.collection.JavaConversions._


/**
 * 6/7/15 WilliamZhu(allwefantasy@gmail.com)
 */

trait HadoopAction {
  this: AppAction =>


  @RequestMapping(Array("cleanHadoop.html"))
  def cleanHadoop(req: HttpServletRequest) = {
    val params = putToReqAttribute(req)
    val res = slaveService.cleanHadoop(params("appName"))

    nav(req, res,
      prePath = (s"#", "清理hadoop"),
      nextPath = (s"#", "#")
    )

    "shellCommandExecuteResult"
  }
  def hadoopConfigure(req: HttpServletRequest, app: String, step: String, slave: Array[String]): Unit = {
    if (app != "hadoop") return
    val stepName = if (app == "hadoop" && step.isEmpty) {
      req.setAttribute("step", "next")
      "Name node 节点选取"
    } else if (app == "hadoop" && step == "next") {
      req.setAttribute("step", "finish")
      val iterKVs = new util.HashMap[String, String]()
      iterKVs.put("nameNodes", slave.mkString(","))
      req.setAttribute("iterKVs", iterKVs)
      "Data node 节点选取"
    } else {
      val iterKVs = new util.HashMap[String, String]()
      iterKVs.put("nameNodes", req.getParameter("nameNodes"))
      iterKVs.put("dataNodes", slave.mkString(","))
      iterKVs.put("slave", (req.getParameter("nameNodes").split(",").toSet ++ slave.toSet).mkString(","))
      req.setAttribute("iterKVs", iterKVs)
      val zks:util.List[String] = slaveService.findAppNamesByApp("zookeeper").split(",").toList
      req.setAttribute("zks",zks)
      ""
    }
    req.setAttribute("configureType",app)
    req.setAttribute("stepName", stepName)
  }

  @RequestMapping(value = Array("removeSlaves.html"), method = Array(RequestMethod.GET))
  def removeSlaves(req: HttpServletRequest) = {
    import scala.collection.JavaConversions._
    val params = putToReqAttribute(req)
    val filter = params.getOrElse("filter", "")

    val appName = params("appName")
    val app = slaveService.getAPPExtra(appName, "app")
    val version = slaveService.getAPPExtra(appName, "version")
    val dataNodes = slaveService.getAPPExtra(appName,"dataNodes")
    val dataNodesSet = dataNodes.split(",").toSet
    req.setAttribute("iterKVs", new java.util.HashMap[String, String]())

    val temp = formatIP(slaveService.getSlave()).filterNot(f => f.docker.enable).filter(f=>dataNodesSet.contains(f.getHostName))
    val slaves: util.List[SlaveBean] = if (!filter.isEmpty)
      temp.filter {
        f =>
          filter.r.findFirstIn(f.getHostName) match {
            case Some(i) => true
            case None => false
          }
      }
    else temp

    req.setAttribute("slave", slaves)
    req.setAttribute("app", app)
    req.setAttribute("version", version)
    req.setAttribute("page", "installManager")
    req.setAttribute("title", "移除data node 节点")
    req.setAttribute("nextStep", params("nextStep")) // /app/addSlaves.html || /app/addHbaseSlaves.html

    "appInstallSelectSlave"
  }

  @RequestMapping(value = Array("removeSlaves.html"), method = Array(RequestMethod.POST))
  def removeSlavesPost(req: HttpServletRequest) = {
    val params = putToReqAttribute(req)
    val appName = params("appName")
    val slaves = params("slave")
    val ress = new scala.collection.mutable.ArrayBuffer[Map[String,AnyRef]]()

    val res = slaveService.startSpecificDataNodes(appName,slaves,"stop")
    ress += Map("name"->"stop data node","rs"->res)

    val dataNodes = slaveService.getAPPExtra(appName,"dataNodes").split(",").toSet
    val newDataNodes = dataNodes -- slaves.split(",").toSet
    val res2 = slaveService.putAPPExtra(appName,Map("dataNodes" -> newDataNodes.mkString(",")))
    ress += Map("name"->"update data node info","rs"->res2)

    val res3 = slaveService.haddoopC(appName,slaves,encode(s"rm -rf ${Constants.appInfoRootDir}/$appName"))
    ress += Map("name"->s"remove data node $slaves","rs"-> res3)

    nav(req, ress.toList,
      nextPath = (s"#", "-")
    )
    "multiShellCommandExecuteResult"
  }

  @RequestMapping(value = Array("addSlaves.html"), method = Array(RequestMethod.GET))
  def addSlaves(req: HttpServletRequest) = {
    import scala.collection.JavaConversions._
    val params = putToReqAttribute(req)
    val filter = params.getOrElse("filter", "")

    val appName = params("appName")
    val app = slaveService.getAPPExtra(appName, "app")
    val version = slaveService.getAPPExtra(appName, "version")


    req.setAttribute("iterKVs", new java.util.HashMap[String, String]())

    val temp = formatIP(slaveService.getSlave()).filterNot(f => f.docker.enable)
    val slaves: util.List[SlaveBean] = if (!filter.isEmpty)
      temp.filter {
        f =>
          filter.r.findFirstIn(f.getHostName) match {
            case Some(i) => true
            case None => false
          }
      }
    else temp

    req.setAttribute("slave", slaves)
    req.setAttribute("app", app)
    req.setAttribute("version", version)
    req.setAttribute("page", "installManager")
    req.setAttribute("title", "添加data node 节点")
    req.setAttribute("nextStep", params("nextStep")) // /app/addSlaves.html || /app/addHbaseSlaves.html

    "appInstallSelectSlave"
  }

  @RequestMapping(value = Array("addSlaves.html"), method = Array(RequestMethod.POST))
  def addSlavesPost(req: HttpServletRequest) = {
    val params = putToReqAttribute(req)
    val res = slaveService.addSlaves(params("appName"), params("slave")).toList
    nav(req, res,
      nextPath = (s"/app/startDataNodes.html?appName=hadoop&nextPath=-&prePath=-", "启动新增data node")
    )
    "multiShellCommandExecuteResult"
  }

  @RequestMapping(Array("hadoop.html"))
  def hadoop(req: HttpServletRequest): String = {
    val params = putToReqAttribute(req)
    val appName = params.getOrElse("appName", "-")
    val app = slaveService.getAPPExtra(appName,"app")
    if (appName != "-") {
      req.setAttribute("appName", appName)
      if(app == "hadoop")
      req.setAttribute("url",s"/app/sycHosts.html?appName=${appName}")
      else if(app == "hbase"){
        req.setAttribute("url",s"/app/startHbaseMaster.html?appName=${appName}")
      }
      return "initConfigureAndStartNav"
    }

    val appNames = slaveService.findAppNamesByApp(params("app"))
    val appNameList = if (appNames.isEmpty) List() else appNames.split(",").toList
    val pageRender = Map("appNames" -> appNameList)
    req.setAttribute("r", toJavaMap(pageRender))
    "configureAndStartNav"
  }

  @RequestMapping(Array("sycHosts.html"))
  def sycHosts(req: HttpServletRequest) = {
    val params = putToReqAttribute(req)
    val res = slaveService.sycHosts(params("appName"))
    nav2(req, params, res,
      prePath = (s"#", "-"),
      nextPath = (s"/app/startQJM.html?appName=${params("appName")}", "启动QJM")
    )

    "shellCommandExecuteResult"
  }

  @RequestMapping(Array("startQJM.html"))
  def startQJM(req: HttpServletRequest) = {
    val params = putToReqAttribute(req)
    val res = slaveService.startQJM(params("appName"), params.getOrElse("action", "start"))

    nav2(req, params, res,
      prePath = (s"#", "启动QJM"),
      nextPath = (s"/app/formatNameNodes.html?appName=${params("appName")}", "格式化NameNode节点")
    )

    "shellCommandExecuteResult"
  }

  // /data/1/journal/node/local/data/mammuthus/current

  @RequestMapping(Array("formatNameNodes.html"))
  def formatNameNodes(req: HttpServletRequest) = {
    val params = putToReqAttribute(req)
    val res = slaveService.formatNameNodes(params("appName"))

    nav2(req, params, res,
      prePath = (s"#", "#"),
      nextPath = (s"/app/copyNameNodes.html?appName=${params("appName")}", "复制NameNode节点")
    )
    "shellCommandExecuteResult"
  }

  @RequestMapping(Array("copyNameNodes.html"))
  def copyNameNodes(req: HttpServletRequest) = {
    val params = putToReqAttribute(req)
    val res = slaveService.copyNameNodes(params("appName"))

    nav2(req, params, res,
      prePath = (s"#", "格式化NameNode节点"),
      nextPath = (s"/app/startNameNodes.html?appName=${params("appName")}", "启动NameNode节点")
    )
    "shellCommandExecuteResult"
  }

  @RequestMapping(Array("startNameNodes.html"))
  def startNameNodes(req: HttpServletRequest) = {
    val params = putToReqAttribute(req)
    val res = slaveService.startNameNodes(params("appName"), params.getOrElse("action", "start"))

    nav2(req, params, res,
      prePath = (s"#", "启动NameNode节点"),
      nextPath = (s"/app/startDataNodes.html?appName=${params("appName")}", "启动DataNode节点")
    )
    "shellCommandExecuteResult"
  }

  @RequestMapping(Array("startDataNodes.html"))
  def startDataNodes(req: HttpServletRequest) = {
    val params = putToReqAttribute(req)
    val res = slaveService.startDataNodes(params("appName"),params.getOrElse("action", "start"))

    nav2(req, params, res,
      prePath = (s"#", "启动DataNode节点"),
      nextPath = (s"/app/formatZK.html?appName=${params("appName")}", "初始化zkfc")
    )
    "shellCommandExecuteResult"
  }

  @RequestMapping(Array("formatZK.html"))
  def formatZK(req: HttpServletRequest) = {
    val params = putToReqAttribute(req)
    val res = slaveService.formatZK(params("appName"))

    nav2(req, params, res,
      prePath = (s"#", "初始化zkfc"),
      nextPath = (s"/app/startZkfc.html?appName=${params("appName")}", "启动zkfc")
    )
    "shellCommandExecuteResult"
  }

  @RequestMapping(Array("startZkfc.html"))
  def startZkfc(req: HttpServletRequest) = {
    val params = putToReqAttribute(req)
    val res = slaveService.startZkfc(params("appName"))

    nav2(req, params, res,
      prePath = (s"#", "启动zkfc"),
      nextPath = (s"/app/startYarn.html?appName=${params("appName")}", "启动Yarn")
    )
    "shellCommandExecuteResult"
  }

  @RequestMapping(Array("startYarn.html"))
  def startYarn(req: HttpServletRequest) = {
    val params = putToReqAttribute(req)
    val sres = new scala.collection.mutable.ArrayBuffer[Map[String,AnyRef]]()
    val res = slaveService.startResourceManager(params("appName"),params.getOrElse("action", "start"))
    sres += Map("name" -> "start resource mananger", "rs" -> res)
    val res2 = slaveService.startNodeManager(params("appName"),params.getOrElse("action", "start"))
    sres += Map("name" -> "start node mananger", "rs" -> res2)
    nav(req, sres.toList,
      nextPath = (s"/app/hadoop.html?app=hadoop", "hadoop管理")
    )
    "multiShellCommandExecuteResult"
  }

}
